package com.smag.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smag.common.constant.SystemConstants;
import com.smag.common.constant.UserConstants;
import com.smag.common.core.domain.AjaxResult;
import com.smag.common.core.domain.TreeSelect;
import com.smag.common.core.domain.entity.*;

import com.smag.common.core.text.Convert;
import com.smag.common.exception.ServiceException;
import com.smag.common.utils.DateUtils;
import com.smag.common.utils.SecurityUtils;
import com.smag.common.utils.StringUtils;

import com.smag.common.utils.bean.BeanUtils;
import com.smag.common.utils.spring.SpringUtils;
import com.smag.system.domain.vo.CascaderVo;
import com.smag.system.domain.vo.CategoryVo;
import com.smag.system.mapper.FarmCategoryMapper;
import com.smag.system.mapper.FarmTechMapper;
import com.smag.system.service.FarmArticleService;
import com.smag.system.service.FarmCategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
* @author hzqhzq
* @description 针对表【farm_category(分类表)】的数据库操作Service实现
* @createDate 2023-03-31 10:19:04
*/
@Service
public class FarmCategoryServiceImpl extends ServiceImpl<FarmCategoryMapper, FarmCategory>
    implements FarmCategoryService {
    @Resource
    private FarmCategoryMapper farmCategoryMapper;
    @Resource
    private FarmTechMapper farmTechMapper;
    @Autowired
    private FarmArticleService farmArticleService;

    @Override
    public AjaxResult getCategoryList() {
        LambdaQueryWrapper<FarmArticle> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FarmArticle::getStatus, SystemConstants.ARTICLE_STATUS_NORMAL);
        List<FarmArticle> list = farmArticleService.list(queryWrapper);
        Set<Long> categoryIds = list.stream()
                .map(article -> article.getCategoryId())
                .collect(Collectors.toSet());
        List<FarmCategory> categories = listByIds(categoryIds);
        categories = categories.stream()
                .filter(category -> category.getStatus().equals(SystemConstants.CATEGORY_STATUS_NORMAL))
                .collect(Collectors.toList());
        List<CategoryVo> categoryVos = BeanUtils.copyBeanList(categories, CategoryVo.class);
        return AjaxResult.success(categoryVos);
    }

    @Override
    public AjaxResult selectAllCategory() {
        LambdaQueryWrapper<FarmCategory> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FarmCategory::getPid,SystemConstants.CATEGORY_PID_FATHER);
        queryWrapper.eq(FarmCategory::getStatus,SystemConstants.CATEGORY_STATUS_NORMAL);
        List<FarmCategory> list = list(queryWrapper);
        List<CategoryVo> categoryVos = BeanUtils.copyBeanList(list, CategoryVo.class);
        List<CascaderVo> cascaderVos = categoryVos.stream()
                .map(categoryVo -> new CascaderVo(categoryVo.getId(), categoryVo.getName(), getChildren(categoryVo.getId())))
                .collect(Collectors.toList());
        return AjaxResult.success(cascaderVos);
    }

    @Override
    public AjaxResult selectAllCategoryChildren() {
        LambdaQueryWrapper<FarmCategory> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ne(FarmCategory::getPid,SystemConstants.CATEGORY_PID_FATHER);
        queryWrapper.eq(FarmCategory::getStatus,SystemConstants.CATEGORY_STATUS_NORMAL);
        List<FarmCategory> list = list(queryWrapper);
        List<CategoryVo> categoryVos = BeanUtils.copyBeanList(list, CategoryVo.class);
        return AjaxResult.success(categoryVos);
    }

    private List<CascaderVo> getChildren(Long categoryId){
        LambdaQueryWrapper<FarmCategory> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FarmCategory::getPid,categoryId);
        queryWrapper.eq(FarmCategory::getStatus,SystemConstants.CATEGORY_STATUS_NORMAL);
        List<FarmCategory> list = list(queryWrapper);
        List<CategoryVo> categoryVos = BeanUtils.copyBeanList(list, CategoryVo.class);
        List<CascaderVo> cascaderVos = categoryVos.stream()
                .map(categoryVo -> new CascaderVo(categoryVo.getId(), categoryVo.getName(), null))
                .collect(Collectors.toList());
        return cascaderVos;
    }

    @Override
    public AjaxResult listAllCategory() {
        LambdaQueryWrapper<FarmCategory> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FarmCategory::getStatus,SystemConstants.CATEGORY_STATUS_NORMAL);
        queryWrapper.eq(FarmCategory::getDelFlag,SystemConstants.ARTICLE_STATUS_NORMAL);
        return AjaxResult.success(farmCategoryMapper.selectList(queryWrapper));
    }


    /**
     * 查询种类
     *
     * @param id 种类主键
     * @return 种类
     */
    @Override
    public FarmCategory selectFarmCategoryById(Long id)
    {
        return farmCategoryMapper.selectFarmCategoryById(id);
    }

    /**
     * 查询种类列表
     *
     * @param farmCategory 种类
     * @return 种类
     */
    @Override
    public List<FarmCategory> selectFarmCategoryList(FarmCategory farmCategory)
    {
        return farmCategoryMapper.selectFarmCategoryList(farmCategory);
    }

    @Override
    public void checkCategoryDataScope(Long id) {
        if (!SysUser.isAdmin(SecurityUtils.getUserId()))
        {
            FarmCategory farmCategory=new FarmCategory();
            farmCategory.setId(id);
            List<FarmCategory> categories= SpringUtils.getAopProxy(this).selectFarmCategoryList(farmCategory);
            if(StringUtils.isEmpty(categories)){
                throw new ServiceException("没有权限访问分类数据");
            }
        }
    }

    /**
     * 校验种类名称是否唯一
     * @param category 种类信息
     * @return 结果
     */
    @Override
    public boolean checkCategoryNameUnique(FarmCategory category) {
        Long CategoryId = StringUtils.isNull(category.getId()) ? -1L : category.getId();
        FarmCategory info = farmCategoryMapper.checkCategoryNameUnique(category.getName(), category.getPid());
        if (StringUtils.isNotNull(info) && info.getId().longValue() != CategoryId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 新增保存种类信息
     * @param farmCategory
     * @return
     */
    @Override
    public int insertFarmCategory(FarmCategory farmCategory)
    {
       /* 测试未通过
        FarmCategory info= farmCategoryMapper.selectFarmCategoryById(farmCategory.getPid());
        //如果父节点不为正常状态，则不允许新增节点
        if (!UserConstants.CATE_NORMAL.equals(info.getStatus())){
            throw new ServiceException("分类停用，不允许新增");
        }
        farmCategory.setAncestors(info.getAncestors()+","+farmCategory.getPid());
        */
        farmCategory.setCreateTime(DateUtils.getNowDate());
        return farmCategoryMapper.insertFarmCategory(farmCategory);
    }

    /**
     * 是否存在子节点
     * @param id 种类ID
     * @return 结果
     */
    @Override
    public boolean hasChildCategoryById(Long id) {
        int result=farmCategoryMapper.hasChildByCategoryById(id);
        return result>0;
    }

    /**
     * 查询种类是否存在作物
     * @param id 种类ID
     * @return 结果true存在 false不存在
     */
    @Override
    public boolean checkCategoryExistCrop(Long id) {
        /*
        int result = farmCategoryMapper.checkCategoryExistCrop(ids）;
        renturn result >0;
         */
        return false;
    }

    /**
     * 修改种类
     *
     * @param farmCategory 种类
     * @return 结果
     */
    @Override
    public int updateFarmCategory(FarmCategory farmCategory)
    {
        FarmCategory newParentCategory =farmCategoryMapper.selectFarmCategoryById(farmCategory.getPid());
        FarmCategory oldCategory = farmCategoryMapper.selectFarmCategoryById(farmCategory.getId());
        if (StringUtils.isNotNull(newParentCategory)&&StringUtils.isNotNull(oldCategory))
        {
            String newAncestors = newParentCategory.getAncestors() + "," + newParentCategory.getId();
            String oldAncestors = oldCategory.getAncestors();
            farmCategory.setAncestors(newAncestors);
            updateFarmCategoryChildren(farmCategory.getId(),newAncestors,oldAncestors);
        }
        int result = farmCategoryMapper.updateFarmCategory(farmCategory);
        if (UserConstants.CATE_NORMAL.equals(farmCategory.getStatus()) && StringUtils.isNotEmpty(farmCategory.getAncestors())
                && !StringUtils.equals("0", farmCategory.getAncestors()))
        {
            // 如果该部门是启用状态，则启用该部门的所有上级部门
            updateParentCategoryStatusNormal(farmCategory);
        }
        return result;
    }

    /**
     * 修改子元素关系
     * @param id 被修改的种类ID
     * @param newAncestors 新的父ID集合
     * @param oldAncestors 旧的父ID集合
     */
    @Override
    public void updateFarmCategoryChildren(Long id, String newAncestors, String oldAncestors) {
        List<FarmCategory> children = farmCategoryMapper.selectChildrenCategoryById(id);
        for (FarmCategory child : children)
        {
            child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
        }
        if (children.size() > 0)
        {
            farmCategoryMapper.updateCategoryChildren(children);
        }
    }

    /**
     * 修改该种类的父级信息
     * @param category 种类信息
     */
    public void updateParentCategoryStatusNormal(FarmCategory category) {
        String ancestors = category.getAncestors();
        Long[] categoryIds = Convert.toLongArray(ancestors);
        farmCategoryMapper.updateCategoryStatusNormal(categoryIds);
    }

    /**
     * 删除种类
     *
     * @param id 需要删除的种类主键
     * @return 结果
     */
    @Override
    public int deleteFarmCategoryById(Long id)
    {
        return farmCategoryMapper.deleteFarmCategoryById(id);
    }

    @Override
    /**
     *查询种类管理数据
     */
    public List<FarmCategory> selectCategoryList(FarmCategory farmCategory) {
        return farmCategoryMapper.selectFarmCategoryList(farmCategory);
    }

    /**
     * 查询种类树信息
     * @param category 种类信息
     * @return 种类树集合
     */
    @Override
    public List<TreeSelect> selectCategoryTreeList(FarmCategory category) {
        List<FarmCategory> categories = SpringUtils.getAopProxy(this).selectCategoryList(category);
        return buildCategoryTreeSelect(categories);
    }

    /**
     * 构建前端所需要树结构
     * @param categorys 种类列表
     * @return 树结构列表
     */
    @Override
    public List<FarmCategory> buildCategoryTree(List<FarmCategory> categorys) {
        List<FarmCategory> returnList = new ArrayList<FarmCategory>();
        List<Long> tempList = categorys.stream().map(FarmCategory::getId).collect(Collectors.toList());
        for (FarmCategory category : categorys)
        {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(category.getPid()))
            {
                recursionFn(categorys, category);
                returnList.add(category);
            }
        }
        if (returnList.isEmpty())
        {
            returnList = categorys;
        }
        return returnList;
    }


    private void recursionFn(List<FarmCategory> list, FarmCategory t) {
        // 得到子节点列表
        List<FarmCategory> childList = getChildList(list, t);
        t.setChildren(childList);
        for (FarmCategory tChild : childList)
        {
            if (hasChild(list, tChild))
            {
                recursionFn(list, tChild);
            }
        }
    }

    private boolean hasChild(List<FarmCategory> list, FarmCategory t) {
        return getChildList(list, t).size() > 0;
    }

    /**
     * 得到子节点列表
     */
    private List<FarmCategory> getChildList(List<FarmCategory> list, FarmCategory t)
    {
        List<FarmCategory> tlist = new ArrayList<FarmCategory>();
        Iterator<FarmCategory> it = list.iterator();
        while (it.hasNext())
        {
            FarmCategory n = (FarmCategory) it.next();
            if (StringUtils.isNotNull(n.getPid()) && n.getPid().longValue() == t.getId().longValue())
            {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 构建前端所需要的下拉树结构
     * @param categorys 种类列表
     * @return
     */
    @Override
    public List<TreeSelect> buildCategoryTreeSelect(List<FarmCategory> categorys) {
        List<FarmCategory> categoryTrees = buildCategoryTree(categorys);
        return categoryTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    /**
     * 根据作物查询种类树信息
     * @param cropId 作物ID
     * @return
     */
    @Override
    public List<Long> selectCategoryListByCropId(Long cropId) {
        FarmTech crop = farmTechMapper.selectCropById(cropId);
        return farmCategoryMapper.selectCategoryListByCropId(cropId, crop.isCategoryCheckStrictly());
    }

    /**
     * 根据ID查询所有子种类（正常状态）
     * @param id 种类ID
     * @return 子种类数
     */
    @Override
    public int selectNormalChildrenCategoryById(Long id) {
        return farmCategoryMapper.selectNormalChildrenCategoryById(id);
    }

    @Override
    public AjaxResult getRootCategoryList() {
        LambdaQueryWrapper<FarmCategory> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FarmCategory::getPid,SystemConstants.CATEGORY_PID_FATHER);
        return AjaxResult.success(list(queryWrapper));
    }


}




